#import "SFUCalendarSource.h"

//  Reference to ElementParser (third party source) used in this class.
//
//  Created by Lee Buck on 4/21/09.
//  Copyright 2009 Blue Bright Ventures. All rights reserved.
//
//	This program is free software: you can redistribute it and/or modify
//	it under the terms of the GNU General Public License as published by
//	the Free Software Foundation, either version 3 of the License, or
//	(at your option) any later version.

//	This program is distributed in the hope that it will be useful,
//	but WITHOUT ANY WARRANTY; without even the implied warranty of
//	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//	GNU General Public License for more details.

//	Commercial licences without many of the obligations of GPL 
//	are available for a nominal fee at sales@touchtankapps.com.

//	You should have received a copy of the GNU General Public License
//	along with this program.  If not, see <http://www.gnu.org/licenses/>.

/**
 * An SFUCalendarSource is an object representing the SFU events 
 * calendar website with its parsable events.
 *
 * Refers to the website "http://events.sfu.ca/" and its branching
 * relevant URLs. Conforms to the WebParsable protocol.
 *
 * Code used within this class and the supporting API was written by Lee Buck.
 * The supporting API can be found in ./ElementParser folder.
 *
 * @author      James Lin
 * @author      Lee Buck
 * @version     1.0.1
 * @since       0.0.4
 * @see         SFUWebSource
 */
@implementation SFUCalendarSource

/**
 * Initialize the SFU calendar source with a URL.
 *
 * The connection is asynchronous.
 *
 * @param sourceURLString  the absolute URL of the SFU calendar website
 * @param theDelegate      the delegate to handle connection events
 * @return                 the initialized SFUCalendarSource
 * @see	                   SFUWebSource#initWithURLString
 * @see	                   SFUConnectionDelegate
 */
- (id) initWithURLString:(NSString*)sourceURLString
				delegate:(id<SFUConnectionDelegate>)theDelegate {
	self = [super initWithURLString:sourceURLString delegate:theDelegate];
	return self;
}

/**
 * Parse the events from the SFU events calendar website.
 *
 * @precondition  the source code has been completely loaded
 * @return        an array of the parsed SFU events
 * @see	          SFUWebSource#parseElements
 */
- (NSArray*) parseElements {
	NSMutableArray* parsedEvents = [[NSMutableArray alloc] init];
	NSString* urlStr = @"https://events.sfu.ca/ViewItem.html?cal_item_id=";
	
	// Begin parse
	document = [Element parseHTML: self.sourceCode];
	
	// Begin parse: select XML <item> tags
	events = [document selectElements:@"item"];
	
	// Process each XML <item> tag as an event
	for (Element* event in events) {
		// Parse the event identifier
		NSString* eventIDString = [[event selectElement:@"link"] contentsText];
		int eventID = [[[[eventIDString componentsSeparatedByString:@"&amp;"] objectAtIndex:0] 
						stringByReplacingOccurrencesOfString:urlStr withString:@""] intValue];
		
		// Parse the event heading
		NSString* eventHeading = [[event selectElement:@"title"] contentsText];
		
		// Parse the event start and end datetime
		NSDateFormatter* dateFormatter = [[[NSDateFormatter alloc] init] autorelease];
		[dateFormatter setDateFormat:@"EEE',' dd MMM yyyy HH:mm ZZZ"];
		NSDate* eventStartDT = [dateFormatter dateFromString:
								[[event selectElement:@"cdaily:eventStartDate"] contentsText]];
		NSDate* eventEndDT = [dateFormatter dateFromString:
							  [[event selectElement:@"cdaily:eventEndDate"] contentsText]];
		
		// Parse the event category
		NSString* eventCategory;
		if ([[event selectElement:@"category"] contentsText] == nil) {
			eventCategory = @"";
		} else {
			eventCategory = [[event selectElement:@"category"] contentsText];
		}
		
		// Parse the event contact info
		NSMutableString* eventContactInfo = [NSMutableString string];
		NSString* appendingString = [[event selectElement:@"cdaily:contactName"] contentsText];
		if (appendingString != nil) {
			[eventContactInfo appendString:appendingString];
		}
		appendingString = [[event selectElement:@"cdaily:contactInfo"] contentsText];
		if (appendingString != nil) {
			[eventContactInfo appendString:@"\n"];
			[eventContactInfo appendString:appendingString];
		}
		appendingString = [[event selectElement:@"cdaily:addlInfoURL"] contentsText];
		if (appendingString != nil) {
			[eventContactInfo appendString:@"\n"];
			[eventContactInfo appendString:appendingString];
		}
		
		// Parse the event description
		NSString* eventDescription = [[event selectElement:@"description"] contentsText];
		if (eventDescription == nil)  {
			eventDescription = @"";
		} else {
			eventDescription = [eventDescription stripTags];
		}
		
		// Parse the event location from event description or heading
		NSString* eventLocation = @"";
		
		if (eventDescription != nil) {
			eventLocation = [ParsingUtilities 
							 parseBuildingFromString:eventDescription].name;
			if (!([eventLocation length] > 0)) {
				eventLocation = [ParsingUtilities 
								 parseBuildingFromString:eventHeading].name;
			}
		}
		
		// Place event information into a temporary event container
		SFUEvent* tempEventInfo = [[SFUEvent alloc] initWithDetails:eventID 
															heading:eventHeading 
														   location:eventLocation 
													  startDateTime:eventStartDT 
														endDateTime:eventEndDT 
														   category:eventCategory 
														contactInfo:eventContactInfo 
														description:eventDescription 
													   isBookmarked:NO];
		// Add event container to the temporary collection
		[parsedEvents addObject:tempEventInfo];
		[tempEventInfo release];
	}
	
	return parsedEvents;
}

/**
 * Deallocate the SFU calendar source.
 */
- (void)dealloc {
	document = nil;
	events = nil;
	[super dealloc];
}

@end
